#define DBC_CHECK_PRECONDITION

using System;
using System.Xml;

using DesignByContract;

using Outcoding.GraphGenerator.Entities;

namespace Outcoding.GraphGenerator.XmlBuilders {
    public class SlideXmlBuilder : IXmlBuilder {
        private Slide mResultObject = null;

        public object ResultObject {
            get {
                return mResultObject;
            }
        }

        public SlideXmlBuilder(XmlNode slideXmlNode) {
            Check.Require(slideXmlNode != null, "Xml source node cannot be null");
            Check.Require(slideXmlNode.Name.CompareTo(XmlTagNames.slide.ToString()) == 0, "A Slide Xml node must be supplied.");
            this.BuildObject(slideXmlNode);
        }

        private void BuildObject(XmlNode slideXmlNode) {
            mResultObject = new Slide();
            try {
                mResultObject.Layout = ParseLayoutAttribute(slideXmlNode);
                if (slideXmlNode.Attributes["index"] != null)
                    mResultObject.Index = ParseIndexAttribute(slideXmlNode);
                else
                    mResultObject.Index = Int32.MinValue;   //used to distinguish a valid index
            } catch (DesignByContract.PreconditionException preExc) {
                //log error
                mResultObject = null;
                throw;
            }
        }

        private SlideLayout ParseLayoutAttribute(XmlNode slideXmlNode) {
            Check.Require(slideXmlNode.Attributes["layout"] != null, "layout attribute not present");
            return ConvertLayoutFromName(slideXmlNode.Attributes["layout"].Value);
        }

        private SlideLayout ConvertLayoutFromName(string layoutName) {
            Check.Require(layoutName != null, "Layout name not defined");

            SlideLayout layoutValue = SlideLayout.ppLayoutUnknown;
            switch(layoutName){
                case "ppLayoutBlank":
                    layoutValue = SlideLayout.ppLayoutBlank;
                    break;
                case "ppLayoutTitleOnly":
                    layoutValue = SlideLayout.ppLayoutTitleOnly;
                    break;
                case "ppLayoutTitle":
                    layoutValue = SlideLayout.ppLayoutTitle;
                    break;
                case "ppLayoutLargeObject":
                    layoutValue = SlideLayout.ppLayoutLargeObject;
                    break;
                case "ppLayoutText":
                    layoutValue = SlideLayout.ppLayoutText;
                    break;
                case "ppLayoutTwoColumnText":
                    layoutValue = SlideLayout.ppLayoutTwoColumnText;
                    break;
                case "ppLayoutObjectOverText":
                    layoutValue = SlideLayout.ppLayoutObjectOverText;
                    break;
                case "ppLayoutTextAndTwoObjects":
                    layoutValue = SlideLayout.ppLayoutTextAndTwoObjects;
                    break;
                case "ppLayoutTwoObjectsAndText":
                    layoutValue = SlideLayout.ppLayoutTwoObjectsAndText;
                    break;
                case "ppLayoutTwoObjectsOverText":
                    layoutValue = SlideLayout.ppLayoutTwoObjectsOverText;
                    break;
                case "ppLayoutFourObjects":
                    layoutValue = SlideLayout.ppLayoutFourObjects;
                    break;
                case "ppLayoutCustom":      //future development, unknown layout for now
                default:
                    break;
            }
            return layoutValue;
        }

        private int ParseIndexAttribute(XmlNode slideXmlNode) {
            Check.Require(slideXmlNode.Attributes["index"] != null, "index attribute not present");
            return Int32.Parse(slideXmlNode.Attributes["index"].Value);
        }

    }
}
